const SocketIOServer = require("socket.io");
const interfaces = require("../util/interfaces");
const amqp = require('amqplib/callback_api');
const child_process = require("child_process");
const Authenticate = require('./Authenticate');
const {
    time
} = require("console");
let roomTeacherMap = new Map();
let socketIdUsernameMap = new Map();
let fileDurationArrs = {};
let isLive = false;
var clientlist = new Map();
var userlist = new Array();

function configSocketIO(server) {
    function listClients(roomName) {
        io.to(roomName).clients((err, clients) => {
            if (!err) {
                let usernames = clients.map(x => socketIdUsernameMap.get(x) ? socketIdUsernameMap.get(x) : x);
                io.to(roomName).emit("listClients", usernames);
            }
        });
    }

    let io = SocketIOServer(server, {
        cors: {
            origin: '*'
        },

    });
    io.use((socket, next) => {

        let token = socket.handshake.query.token;
        if (typeof (token) != 'undefined' && token != '') {
            var flag = Authenticate.Authenticate(token)

            if (flag) {
                return next();
            }
        }
        return next(new Error('authentication error'));

        // return next();
    });
    // let url = {
    //     protocol: 'amqp',
    //     hostname: '127.0.0.1',
    //     port: 5672,
    //     username: 'chenjinyin',
    //     password: '123qwe',
    //     vhost: 'erp'
    //   }

    //   amqp.connect(url,(connError, connection)=>{
    //     if(connError){
    //       throw connError;
    //     }
    //     connection.createChannel((channelError, channel)=>{
    //       if(channelError){
    //         throw channelError;
    //       }
    //       const QUEUE = 'chatmessage';
    //       channel.assertQueue(QUEUE);
    //       //订阅  或者 消费
    //       channel.consume(QUEUE,(msg)=>{
    //         /*监听消息队列，一旦有用户发送消息，马上触发消费，
    //           把消费的信息发送给目标订单管理员的客户端
    //       */
    //      console.log(msg.content.toString());
    //      //进行数据得转发
    //      io.to(roomName).emit("gotMsg", socketIdUsernameMap.get(socket.id), content);
    //     //  io.emit('msg',msg.content.toString());


    //       },{
    //         noAck: true
    //       })

    //     })
    //   });

    function hashFunc(str, size) {

        //定义一个变量来存储hashCode
        var hashCode = 0;

        // 利用霍纳法则计算出hashCode的值
        // give -> Unicode编码
        for (var i = 0; i < str.length; i++) {
            hashCode = 37 * hashCode + str.charCodeAt(i);
        }

        // 利用hashCode与哈希表的长度取余得到下标值
        var index = hashCode % size;

        return index;
    }

    io.on("connection", socket => {
        socket.on("conn", () => {
            console.log("连接成功")
        })

        //创建房间
        socket.on("createClassroom", (name, username, callback) => {
            if (!io.sockets.adapter.rooms[name]) {
                console.log();
                console.log("==========创建房间开始=================")
                console.log(name + "房间创建成功" + name);
                socket.join(name);
                listClients(name);

                roomTeacherMap.set(name, socket.id);
                socketIdUsernameMap.set(socket.id, username);
                console.log(socket.id + ' ' + username);
                callback(true);
                console.log("==========创建房间结束=================")
            } else {
                callback(false);
            }
            //监听谁退出房间了
            socket.on("disconnect", function () {
                console.log();
                console.log("=========退出房间开始==================")
                console.log("退出房间")
                roomTeacherMap.delete(name);
                socketIdUsernameMap.delete(socket.id);
                console.log("==========退出房间结束=================")
            });
        });
        //离开房间
        socket.on("leave", (name, username, callback) => {
            console.log();
            console.log("=========退出房间开始==================")
            console.log("退出房间")
            socket.leave(name)
            //io.to(name).emit('studentLeave', {studentSid: socket.id});
            listClients(name);
            roomTeacherMap.delete(name);
            socketIdUsernameMap.delete(socket.id);
            callback(true);
            console.log("==========退出房间结束=================")
        })
        //加入房间
        socket.on("joinClassroom", (name, username, callback) => {
            console.log();
            console.log("=========加入房间开始==================")
            socket.join(name);
            callback();
            console.log(username + "加入" + name);
            listClients(name);
            socketIdUsernameMap.set(socket.id, username);
            io.to(roomTeacherMap.get(name)).emit("studentJoinedIn", {
                studentSid: socket.id
            });
            console.log();
            console.log("=========加入房间结束==================")
        });
        //房间内发布消息
        socket.on("msg", (roomName, content) => {
            console.log("房间内发布消息")
            console.log('server msg :' + roomName + " " + content);
            console.log(socketIdUsernameMap.get(socket.id))
            io.to(roomName).emit("gotMsg", socketIdUsernameMap.get(socket.id), content);
        });

        socket.on("publishStream", (data, callback) => {
            console.log("publishStream")
            let p = socket.ffmpeg_process = child_process.spawn("ffmpeg", ["-fflags", "nobuffer", "-i", "-", "-vcodec", "copy", "-f", "flv", `rtmp://192.168.23.124/${data.app}/${data.stream}`], {
                detached: true
            });
            p.stderr.on("data", data => {
                // console.log(data.toString());
            });
            p.stdout.on("data", data => {
                // console.log(data.toString());
            });
            p.on("close", (code) => {
                console.log("关闭子进程")
            })
            p.on("error", data => {
                console.log("错误")
                // console.log(data)
            })

            callback(true);
        });

        socket.on("streamData", data => {
            console.log(data)
            if (typeof (socket.ffmpeg_process) == "undefined") {

            } else {
                socket.ffmpeg_process.stdin.write(data);
            }

        });
        socket.on("stopRtmp", (data, fn) => {
            console.log(socket.ffmpeg_process.pid)
            socket.ffmpeg_process.stdin.end();
            // socket.ffmpeg_process.kill();
            var call = process.kill(socket.ffmpeg_process.pid, 'SIGTERM');
            if (call) {
                fn(call, "线程以杀死")
            }
            //   var child_process = require('child_process');
            //   var chile = child_process.exec('"taskkill" /F /IM ffmpeg.exe* /T', function(error, stdout, stderr) {
            //     if (error) {
            //       console.error(`exec error: ${error}`);
            //       return;
            //     }
            //     console.log(`stdout: ${stdout}`);
            //     console.log(`stderr: ${stderr}`);
            //   });

        })
        socket.on('disconnect', function (close) {
            console.log("失去连接")
            if (socket.ffmpeg_process != null) {
                var call = process.kill(socket.ffmpeg_process.pid, 'SIGTERM');
                if (call) {
                    console.log("子线程结束")
                    socket.disconnect(close)
                }
            }

        });
        socket.on('reconnecting', (timeout) => {
            // ...
            console.log("reconnecting")
            console.log(timeout);
        });
        socket.on('ping', (timeout) => {
            // ...
            console.log("ping")
            console.log(timeout)
        });
    });
}


module.exports.configSocketIO = configSocketIO;